import {IAttribute, IFragmentResult, InnerVarying, IUniform, IVarying, Program} from "./Program";
import {Vector3} from "../math/Vector3";
import {Matrix4} from "../math/Matrix4";
import {Vector4} from "../math/Vector4";

export interface MeshVarying  extends IVarying {
    vColor: Vector4;
}
export interface MeshAttribute extends IAttribute  {
    aPosition: Vector3;
    aNormal: Vector3;
}
export interface MeshUniform extends IUniform {
    uLightDire: Vector3;
    uMVPMatrix: Matrix4;
}

export class MeshProgram extends Program<MeshAttribute, MeshUniform, MeshVarying>{

    vertexShader(attribute: MeshAttribute, uniform: MeshUniform): InnerVarying & MeshVarying {
        const {aNormal, aPosition} = attribute;
        const {uMVPMatrix, uLightDire} = uniform;
        const intensity  = Math.abs(aNormal.dot(uLightDire));
        return {
            vPosition: aPosition.appliedMatrix4(uMVPMatrix),
            vColor: new Vector4(intensity, intensity, intensity, 1),
        }
    }

    fragmentShader(varying: InnerVarying & MeshVarying, uniform: MeshUniform): IFragmentResult {
        const {vPosition, vColor} = varying;
        const {} = uniform;
        return {
            discard: false,
            color: vColor,
        }
    }
}